﻿#ifndef QTSOCKET_UDPCHANNEL_H
#define QTSOCKET_UDPCHANNEL_H

#include "qnet_global.h"
#include <QUdpSocket>

#include <common/taskentry.h>
#include <common/taskqueue.h>

QNET_NAMESPACE_BEGIN
class NetReading;
/**
 * @brief 表示udp会话类。
 */
class QNETSHARED_EXPORT UdpChannel : public QObject
{
    Q_OBJECT

public:
    explicit UdpChannel(QObject *parent = nullptr);
public:
    /**
     * @brief bind 绑定本地地址。
     * @param localAddress 本机地址。
     * @param localPort 本机端口。
     * @return 绑定成功返回true。
     */
    bool bind(const QHostAddress &localAddress, quint16 localPort);

    /**
     * @brief setRemote 设置远程信息。
     * @param remoteAddress 远程地址。
     * @param remotePort 远程端口。
     */
    void setRemote(const QHostAddress &remoteAddress, quint16 remotePort);

    /**
     * @brief setReading 网络数据读取接口设置。
     * @param reading 网络数据读取实例。
     */
    void setReading(NetReading* reading);

    /**
     * @brief write 写入数据流。
     * @param data 待写入数据。
     * @return 返回写入数据长度。
     */
    int write(const QByteArray &data);
    /**
     * @brief writeTo 写入数据到指定地址。
     * @param data 数据内容。
     * @param remoteAddr 远端地址。
     * @param remotePort 远端端口。
     * @return 返回写入数据长度。
     */
    int writeTo(const QByteArray &data, const QHostAddress &remoteAddr, quint16 remotePort);
    /**
     * @brief close 关闭会话。
     */
    void close();
    /**
     * @brief remotePort 获取默认远程端口。
     * @return
     */
    quint16 remotePort() const;
    /**
     * @brief remoteAddress 获取默认远程地址。
     * @return
     */
    QHostAddress remoteAddress() const;
    /**
     * @brief localPort 获取本机绑定端口。
     * @return
     */
    quint16 localPort() const;
    /**
     * @brief localAddress 获取本机绑定地址。
     * @return
     */
    QHostAddress localAddress() const;
private:
signals:
    /**
     * @brief doCloseSocket 执行关闭socket的信号。
     */
    void doCloseSocket();
private slots:
    /**
     * @brief read 读取数据槽，开始数据处理。
     */
    void read();
    /**
     * @brief onCloseSocket 关闭信号的槽。
     */
    void onCloseSocket();
private:
    QUdpSocket *m_udp;
    QByteArray m_readDatagram;
    /**
     * @brief m_readQueue 数据读取队列。
     */
    TaskQueue m_readQueue;
    /**
     * @brief m_remoteAddress 远程地址。
     */
    QHostAddress m_remoteAddress;
    /**
     * @brief m_remotePort 远程端口。
     */
    quint16 m_remotePort;
    /**
     * @brief m_reading 数据读取回调。
     */
    NetReading* m_reading;

    friend class InnerProc; // 内部类可访问。
};
QNET_NAMESPACE_END

#endif // UDPSESSION_H
